package com.infolab.aims.service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.infolab.aims.common.PaginationHelper;
import com.infolab.aims.common.QueryHelper;
import com.infolab.aims.common.bean.SearchCriteria;
import com.infolab.aims.common.bean.SearchResult;
import com.infolab.aims.domain.Location;
import com.infolab.aims.domain.Vendor;
import com.infolab.aims.domain.asset.AssetComponent;
import com.infolab.aims.domain.asset.AssetComponentPK;
import com.infolab.aims.domain.asset.AssetConsumption;
import com.infolab.aims.domain.asset.AssetConsumptionDetail;
import com.infolab.aims.domain.asset.AssetEquipment;
import com.infolab.aims.domain.asset.AssetEquipmentPK;
import com.infolab.aims.domain.asset.AssetIssueOrderDetail;
import com.infolab.aims.domain.asset.AssetModel;
import com.infolab.aims.domain.asset.AssetTransaction;
import com.infolab.aims.domain.asset.AssetTransactionItem;
import com.infolab.aims.domain.asset.AssetTransactionItemPK;
import com.infolab.aims.service.intf.AssetModelService;
import com.infolab.aims.service.intf.AssetTransactionService;


@Service
@Transactional
public class AssetTransactionServiceImpl implements AssetTransactionService {
	
	Log logger = LogFactory.getLog(getClass());
	@PersistenceContext
	private EntityManager em;
	
	
	
	@Autowired
	private AssetModelService assetModelService;
	
	private String getNextAssetTag(String assetType,String assetModelCode)
	{
		String assetTag="FA-"+assetType.substring(0, 1)+"-"+assetModelCode+"-"+new SimpleDateFormat("yyyyMMdd").format(new Date())+"-";

		Integer nextVal = (Integer) em.createNativeQuery("select nextval('AMSQ_CT_ASSETTAG') from dual").getSingleResult();

		return assetTag+String.format("%05d", nextVal.intValue());
	}
	
	public String getNextTransactionCode(String assetTransactionType)
	{
		String fmtYYYYMMdd = DateFormatUtils.format(new Date(), "yyyyMMdd");
		Integer nmbr =  (Integer) em.createNativeQuery("select nextval('AMSQ_CT_TRANSACTION_CODE') from dual").getSingleResult();
		
		return assetTransactionType+fmtYYYYMMdd+String.format("%03d", nmbr.intValue());
	}
	
	public String getNextTransactionGenCode(String assetTransactionType)
	{
		String fmtYYYYMMdd = DateFormatUtils.format(new Date(), "yyyyMMdd");
		Integer nmbr =  (Integer) em.createNativeQuery("select nextval('AMSQ_CT_TRANSACTION_GENCODE') from dual").getSingleResult();
		
		return assetTransactionType+fmtYYYYMMdd+String.format("%03d", nmbr.intValue());
	}
	
	public void createInitialBalance(AssetTransaction assetTransaction)
	{
		String assetType = assetTransaction.getAssetType();
		
		AssetTransaction newAssetTransaction = new AssetTransaction();
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_INITIALBALANCE);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		
		assetTransaction.setDateCreated(new Date());
		assetTransaction.setDateModified(new Date());
		assetTransaction.setModifiedBy(assetTransaction.getCreatedBy());
		assetTransaction.setApprovedDate(new Date());
		assetTransaction.setApprovedBy(assetTransaction.getCreatedBy());
		
		assetTransaction.setAssetTransactionCode(getNextTransactionGenCode(AssetTransaction.TRANSACTIONTYPE_INITIALBALANCE));
		
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		
		em.persist(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		if(assetTransactionItems!=null)
		{ int idx = 1;
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
				if(assetTransactionItem.isDeleted()) continue;
				
				if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_EQUIPMENT))
					assetTransactionItem.setAssetTransactionQuantity(1);
				
				if(assetTransactionItem.getAssetTransactionQuantity()==null) continue;
				
				
				AssetModel assetModel = assetTransactionItem.getAssetModel();
				assetModel = em.find(AssetModel.class, assetModel.getAssetModelId());
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(idx);
				idx++;
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_EQUIPMENT))
					assetTransactionItem.setAssetTag(getNextAssetTag(AssetModel.ASSETTYPE_EQUIPMENT, assetModel.getAssetModelCode()));
				else 
					assetTransactionItem.setAssetTag(getNextAssetTag(AssetModel.ASSETTYPE_COMPONENT, assetModel.getAssetModelCode()));
				
				em.persist(assetTransactionItem);
				
				if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_EQUIPMENT))
				{
					AssetEquipment assetEquipment = new AssetEquipment();
					assetEquipment.setAssetModel(assetModel);
					assetEquipment.setCompanyCode(assetTransactionItem.getCompanyCode());
					AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetModel,assetTransactionItem.getSerialNo());
					assetEquipment.setAssetEquipmentPK(assetEquipmentPK);
					assetEquipment.setLocation(assetTransactionItem.getLocation());
					assetEquipment.setUnitPrice(0f);
					assetEquipment.setDateCreated(new Date());
					assetEquipment.setCreatedBy(assetTransaction.getCreatedBy());
					assetEquipment.setDateModified(new Date());
					assetEquipment.setModifiedBy(assetTransaction.getCreatedBy());
					assetEquipment.setAssetEquipmentStatus(AssetModel.ASSETSTATUS_ACTIVE);
					assetEquipment.setAssetTag(assetTransactionItem.getAssetTag());
					em.merge(assetEquipment);
				}
				else if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_COMPONENT))
				{
					AssetComponentPK assetComponentPK = new AssetComponentPK(assetModel, assetTransactionItem.getLocation(),assetTransactionItem.getCompanyCode());
					AssetComponent assetComponent = em.find(AssetComponent.class, assetComponentPK);
					if(assetComponent==null)
					{
						assetComponent = new AssetComponent();
						assetComponent.setAssetComponentPK(assetComponentPK);
						assetComponent.setQuantity(assetTransactionItem.getAssetTransactionQuantity());
						assetComponent.setAssetComponentPK(assetComponentPK );
						assetComponent.setDateCreated(new Date());
						assetComponent.setCreatedBy(assetTransaction.getCreatedBy());
						assetComponent.setDateModified(new Date());
						assetComponent.setModifiedBy(assetTransaction.getCreatedBy());
						
						em.persist(assetComponent);
					}
					else
					{
						assetComponent.setQuantity(assetComponent.getQuantity()+assetTransactionItem.getAssetTransactionQuantity());
						assetComponent.setAssetComponentPK(assetComponentPK );
						assetComponent.setDateCreated(new Date());
						assetComponent.setCreatedBy(assetTransaction.getCreatedBy());
						assetComponent.setDateModified(new Date());
						assetComponent.setModifiedBy(assetTransaction.getCreatedBy());
						em.merge(assetComponent);
					}
					
					em.flush();
					
					createAssetConsumption(assetComponent, assetTransactionItem, assetTransaction);
				}
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
		
	}

	public void updateAssetTransaction(AssetTransaction assetTransaction) {
		
		AssetTransaction newAssetTransaction = em.find(AssetTransaction.class, assetTransaction.getAssetTransactionId());
		
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		
		em.merge(newAssetTransaction);
	}


	public AssetTransaction getAssetTransaction(Integer id) {
		
		AssetTransaction assetTransaction = em.find(AssetTransaction.class, id);
		assetTransaction.getAssetTransactionItems().size();
		return assetTransaction;
	}

	public AssetTransaction findAssetTransaction(SearchCriteria searchCriteria) {
		Query query = em.createQuery("from AssetTransaction");
		
		return null;
	}

	public SearchResult searchAssetTransaction(
			SearchCriteria searchCriteria) {
		AssetTransactionPaginationHelper helper = new AssetTransactionPaginationHelper();
		
		return helper.getSearchResultFromQueryHelper(em, searchCriteria);
	}
	
	public void deleteAssetTransaction(Integer assetTransactionId) {
		
		Query query = em.createQuery("update AssetTransaction set active=0 where assetTransactionId=:assetTransactionId");
		
		query.setParameter("assetTransactionId", assetTransactionId);
		
		query.executeUpdate();
		
	}
	
	

	public AssetTransaction findInitialBalance(Integer assetModelId) {
		Query query =em.createNamedQuery("AssetTransaction.findByAssetModel");
		query.setParameter("assetModelId", assetModelId);
		List list = query.getResultList();
		if(list!=null && list.size()!=0)
			return (AssetTransaction) list.get(0);
		
		return null;
	}

	public void createIssueOrderComponents(AssetTransaction assetTransaction) {
		
		AssetTransaction newAssetTransaction = new AssetTransaction();
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_ISSUEORDER);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		assetTransaction.setDateCreated(new Date());
		assetTransaction.setDateModified(new Date());
		assetTransaction.setModifiedBy(assetTransaction.getCreatedBy());
		assetTransaction.setApprovedDate(new Date());
		assetTransaction.setApprovedBy(assetTransaction.getCreatedBy());
		assetTransaction.setAssetTransactionCode(getNextTransactionCode(AssetTransaction.TRANSACTIONTYPE_ISSUEORDER));
		assetTransaction.setAssetType(AssetModel.ASSETTYPE_COMPONENT);
		
		logger.info("Create issue component " + assetTransaction.getAssetTransactionCode());
		
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		em.persist(newAssetTransaction);
		
		Location location = assetTransaction.getFromLocation();
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		List<AssetIssueOrderDetail> orders = new ArrayList<AssetIssueOrderDetail>();
		int idx=1;
		if(assetTransactionItems!=null)
		{
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
				
				if(assetTransactionItem.isDeleted()) continue;
				if(assetTransactionItem.getAssetTransactionQuantity()==null) continue;				
				
				AssetModel assetModel = assetTransactionItem.getAssetModel();
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(idx);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				
				
				AssetComponentPK assetComponentPK = new AssetComponentPK(assetModel, location,assetTransaction.getCompanyCode());
				AssetComponent assetComponent = em.find(AssetComponent.class, assetComponentPK);
				if(assetComponent!=null)
				{
					
					assetComponent.setQuantity(assetComponent.getQuantity()-assetTransactionItem.getAssetTransactionQuantity());
					assetComponent.setAssetComponentPK(assetComponentPK );
					
					logger.info("Asset component " + assetModel.getAssetModelCode()+" "+assetComponent.getQuantity());
					em.merge(assetComponent);
					
					// FIFO Price
					// by the time i wrote this code, only God and i know
					Float assetPrice = getNextAssetPrice(assetTransaction,assetComponent,assetTransactionItem.getAssetTransactionQuantity().intValue(), orders);
					assetTransactionItem.setAssetPrice(assetPrice);
				}
				
				em.persist(assetTransactionItem);
				idx++;
				//save detail

			}
		}
		
		for(AssetIssueOrderDetail detail : orders){
			detail.setAssetTransaction(newAssetTransaction);
			em.persist(detail);
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}

	private Float getNextAssetPrice(AssetTransaction assetTransaction,AssetComponent assetComponent,int qtyConsumption, List<AssetIssueOrderDetail> orders) {
		
		Query query= em.createQuery("from AssetConsumption assetConsumption where assetConsumption.assetComponent.assetComponentPK.assetModel.assetModelId=:assetModelId and assetConsumption.assetComponent.assetComponentPK.location.locationId=:locationId and assetConsumption.assetComponent.assetComponentPK.companyCode=:companyCode and assetConsumption.assetConsumptionStatus=1 order by assetConsumption.dateCreated asc");
		query.setParameter("assetModelId", assetComponent.getAssetComponentPK().getAssetModel().getAssetModelId());
		query.setParameter("companyCode", assetComponent.getAssetComponentPK().getCompanyCode());
		query.setParameter("locationId", assetComponent.getAssetComponentPK().getLocation().getLocationId());
		List<AssetConsumption> assetConsumptions  = query.getResultList();
		
		float assetPrice = 0;
		if(assetConsumptions!=null)
		{
			for(int i=0;i<assetConsumptions.size();i++)
			{
				AssetConsumption assetConsumption = assetConsumptions.get(i);
				int qtyAvailableToUse = assetConsumption.getQuantityReceived()-assetConsumption.getQuantityUsed();
				int qtyUsed = 0;
				if(qtyConsumption<=qtyAvailableToUse)
				{
					AssetConsumptionDetail assetConsumptionDetail = new AssetConsumptionDetail();
					assetConsumptionDetail.setAssetConsumption(assetConsumption);
					assetConsumptionDetail.setQuantityBefore(qtyAvailableToUse);
					
					qtyUsed = assetConsumption.getQuantityUsed().intValue()+qtyConsumption;
					assetConsumption.setQuantityUsed(qtyUsed);
					if(qtyUsed==assetConsumption.getQuantityReceived().intValue())
					{
						assetConsumption.setAssetConsumptionStatus(false);
					}
					assetPrice += (qtyConsumption*assetConsumption.getUnitPrice());
					
					assetConsumption.setDateModified(new Date());
					
					em.merge(assetConsumption);
					
					assetConsumptionDetail.setQuantityUsed(qtyConsumption);
					assetConsumptionDetail.setDateCreated(new Date());
					assetConsumptionDetail.setDateModified(new Date());
					assetConsumptionDetail.setRefNo(assetTransaction.getAssetTransactionCode());
					assetConsumptionDetail.setTransactionType(assetTransaction.getAssetTransactionType());
					
					em.persist(assetConsumptionDetail);
					
					// add new logis here
					AssetIssueOrderDetail orderDetail = new AssetIssueOrderDetail();
					orderDetail.setDateCreated(new Date());
					orderDetail.setCreatedByName(assetTransaction.getCreatedBy());
					orderDetail.setDateModified(new Date());
					orderDetail.setModifiedByName(assetTransaction.getCreatedBy());
					orderDetail.setQuantity(qtyConsumption);
					orderDetail.setUnitPrice(assetConsumption.getUnitPrice());
					orders.add(orderDetail);
					
					qtyConsumption=0;
					break;
				}
				else
				{
					AssetConsumptionDetail assetConsumptionDetail = new AssetConsumptionDetail();
					assetConsumptionDetail.setAssetConsumption(assetConsumption);
					assetConsumptionDetail.setQuantityBefore(qtyAvailableToUse);
					assetPrice += (qtyAvailableToUse*assetConsumption.getUnitPrice());
					assetConsumption.setQuantityUsed(assetConsumption.getQuantityReceived());
					
					assetConsumption.setAssetConsumptionStatus(false);
					
					assetConsumption.setDateModified(new Date());
					
					em.merge(assetConsumption);
					
					assetConsumptionDetail.setQuantityUsed(qtyAvailableToUse);
					assetConsumptionDetail.setDateCreated(new Date());
					assetConsumptionDetail.setDateModified(new Date());
					assetConsumptionDetail.setRefNo(assetTransaction.getAssetTransactionCode());
					assetConsumptionDetail.setTransactionType(assetTransaction.getAssetTransactionType());
					
					em.persist(assetConsumptionDetail);
					
					qtyConsumption -=qtyAvailableToUse;
					
					// add new logis here
					AssetIssueOrderDetail orderDetail = new AssetIssueOrderDetail();
					orderDetail.setDateCreated(new Date());
					orderDetail.setCreatedByName(assetTransaction.getCreatedBy());
					orderDetail.setDateModified(new Date());
					orderDetail.setModifiedByName(assetTransaction.getCreatedBy());
					orderDetail.setQuantity(qtyAvailableToUse);
					orderDetail.setUnitPrice(assetConsumption.getUnitPrice());
					orders.add(orderDetail);
					
				}
			}
			
			
		}
		
		if(qtyConsumption!=0)
		{
			createAssetConsumptionNonVendor(assetComponent, assetTransaction, qtyConsumption, orders);
		}
		return assetPrice;
	}

	public void createStockTransferEquipments(
			AssetTransaction assetTransaction) {
		AssetTransaction newAssetTransaction = new AssetTransaction();
		
		String type = assetTransaction.getAssetTransactionType()!=null? assetTransaction.getAssetTransactionType():"";
		if(type.contains(AssetTransaction.TRANSACTIONTYPE_FAULTYTRANSFER))
			assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_FAULTYTRANSFER);
		else			
			assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_EQUIPMENTTRANSFER);
		
		
		assetTransaction.setAssetType(AssetModel.ASSETTYPE_EQUIPMENT);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_PENDING);
		assetTransaction.setDateCreated(new Date());
		assetTransaction.setDateModified(new Date());
		assetTransaction.setModifiedBy(assetTransaction.getCreatedBy());
		assetTransaction.setAssetTransactionCode(getNextTransactionCode(AssetTransaction.TRANSACTIONTYPE_EQUIPMENTTRANSFER));
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		em.persist(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		int idx=1;
		if(assetTransactionItems!=null)
		{
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
				
				if(assetTransactionItem.isDeleted()) continue;
				if(assetTransactionItem.getSerialNo()==null) continue;
				
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(idx);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_PENDING);
				em.persist(assetTransactionItem);
				idx++;
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}
	
	public void createInHouseTransferEquipments(AssetTransaction assetTransaction) {
		
		AssetTransaction newAssetTransaction = new AssetTransaction();
		assetTransaction.setAssetType(AssetModel.ASSETTYPE_EQUIPMENT);
		assetTransaction.setDateCreated(new Date());
		assetTransaction.setDateModified(new Date());
		assetTransaction.setModifiedBy(assetTransaction.getCreatedBy());
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_INHOUSETRANSFER);
		assetTransaction.setApprovedBy(assetTransaction.getApprovedBy());
		assetTransaction.setApprovedDate(new Date());
		assetTransaction.setAssetTransactionCode(getNextTransactionCode(AssetTransaction.TRANSACTIONTYPE_INHOUSETRANSFER));
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		em.persist(newAssetTransaction);
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());		
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		if(assetTransactionItems!=null)
		{
			Iterator<AssetTransactionItem> i = assetTransactionItems.iterator();
			
			int idx=1;
			while(i.hasNext())
			{
				AssetTransactionItem assetTransactionItem = i.next();				
				
				if(assetTransactionItem.isDeleted()) 
				{
					i.remove();						
					continue;
				}
			
				if(assetTransactionItem.getSerialNo()==null) 
				{
					i.remove();						
					continue;
				}
				
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(idx);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				em.persist(assetTransactionItem);
				idx++;				
			}		
			
			i = assetTransactionItems.iterator();
			while(i.hasNext())
			{
				AssetTransactionItem assetTransactionItem = i.next();
				if(assetTransactionItem.isApproved())
				{
					AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetTransactionItem.getAssetModel(), assetTransactionItem.getSerialNo());			
					AssetEquipment assetEquipment = em.getReference(AssetEquipment.class, assetEquipmentPK);
					assetEquipment.setLocation(assetTransaction.getToLocation());
					assetEquipment.setAssetEquipmentStatus(AssetModel.ASSETSTATUS_ACTIVE);
					em.merge(assetEquipment);
				}
			}
		}
		
		
	}
	
	public void approveStockTransferEquipments(
			AssetTransaction assetTransaction) {
		
		
		AssetTransaction newAssetTransaction = em.find(AssetTransaction.class, assetTransaction.getAssetTransactionId());
		
		newAssetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		newAssetTransaction.setApprovedBy(assetTransaction.getApprovedBy());
		newAssetTransaction.setApprovedDate(new Date());
		
		em.merge(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		if(assetTransactionItems!=null)
		{
			Iterator<AssetTransactionItem> i = assetTransactionItems.iterator();
			
			int idx=1;
			while(i.hasNext())
			{
				AssetTransactionItem assetTransactionItem = i.next();
				
				if(assetTransactionItem.getAssetTransactionItemPK()==null)
					i.remove();
				else if(assetTransactionItem.getAssetTransactionItemPK().getItemNo()==null)
				{
					
					if(assetTransactionItem.isDeleted()) { 
						i.remove();						
						continue;
					}
					
					if(assetTransactionItem.getSerialNo()==null) 
					{ 
						i.remove();						
						continue;
					}
					
					AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
					assetTransactionItemPK.setAssetTransaction(assetTransaction);
					assetTransactionItemPK.setItemNo(idx);
					assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
					
					String status = assetTransactionItem.getAssetTransactionStatus();
					if(!assetTransactionItem.isApproved())
						status = AssetTransaction.TRANSACTIONSTATUS_REJECTED;
					assetTransactionItem.setAssetTransactionStatus(status);
					
					em.persist(assetTransactionItem);
					idx++;
				}
				else if(assetTransactionItem.isDeleted())
				{
					assetTransactionItem = em.getReference(AssetTransactionItem.class, assetTransactionItem.getAssetTransactionItemPK());
					em.remove(assetTransactionItem);
					i.remove();
				}
				else
				{
					String remarks = assetTransactionItem.getRemarks();
					String status = assetTransactionItem.getAssetTransactionStatus();
					if(!assetTransactionItem.isApproved())
						status = AssetTransaction.TRANSACTIONSTATUS_REJECTED;
					
					assetTransactionItem = em.getReference(AssetTransactionItem.class, assetTransactionItem.getAssetTransactionItemPK());
					assetTransactionItem.setRemarks(remarks);
					
					assetTransactionItem.setAssetTransactionStatus(status);
					assetTransactionItem.getAssetTransactionItemPK().setItemNo(idx);
					em.merge(assetTransactionItem);
					idx++;
				}
			}
			
			
			i = assetTransactionItems.iterator();
			while(i.hasNext())
			{
				AssetTransactionItem assetTransactionItem = i.next();
				if(assetTransactionItem.isApproved())
				{
					AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetTransactionItem.getAssetModel(), assetTransactionItem.getSerialNo());			
					AssetEquipment assetEquipment = em.getReference(AssetEquipment.class, assetEquipmentPK);
					assetEquipment.setLocation(assetTransaction.getToLocation());
					assetEquipment.setSubLocationId(null);
					em.merge(assetEquipment);
				}
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}
	
	public void updateStockTransferEquipments(
			AssetTransaction assetTransaction) {
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		if(assetTransactionItems!=null)
		{
			
			Iterator<AssetTransactionItem> i = assetTransactionItems.iterator();
			
			int idx=1;
			while(i.hasNext())
			{
				AssetTransactionItem assetTransactionItem = i.next();
				
				if(assetTransactionItem.getAssetTransactionItemPK()==null)
					i.remove();
				else if(assetTransactionItem.getAssetTransactionItemPK().getItemNo()==null)
				{
					if(assetTransactionItem.isDeleted()) { 
						i.remove();						
						continue;
					}
					if(assetTransactionItem.getSerialNo()==null) { 
						i.remove();						
						continue;
					}
					
					AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
					assetTransactionItemPK.setAssetTransaction(assetTransaction);
					assetTransactionItemPK.setItemNo(idx);
					assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
					assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_PENDING);
					em.persist(assetTransactionItem);
					idx++;
				}
				else if(assetTransactionItem.isDeleted())
				{
					assetTransactionItem = em.getReference(AssetTransactionItem.class, assetTransactionItem.getAssetTransactionItemPK());
					em.remove(assetTransactionItem);
					i.remove();
				}
				else
				{
					String remarks = assetTransactionItem.getRemarks();
					String status = assetTransactionItem.getAssetTransactionStatus();
					assetTransactionItem = em.getReference(AssetTransactionItem.class, assetTransactionItem.getAssetTransactionItemPK());
					assetTransactionItem.setRemarks(remarks);
					assetTransactionItem.setAssetTransactionStatus(status);
					assetTransactionItem.getAssetTransactionItemPK().setItemNo(idx);
					em.merge(assetTransactionItem);
					idx++;
				}
			}
			
		}
	}

	public void createStockAdjustments(AssetTransaction assetTransaction) {
		
		String assetType = assetTransaction.getAssetType();
		
		AssetTransaction newAssetTransaction = new AssetTransaction();
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_STOCKADJUSTMENT);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		assetTransaction.setDateCreated(new Date());
		assetTransaction.setModifiedBy(assetTransaction.getCreatedBy());
		assetTransaction.setDateModified(new Date());
		assetTransaction.setApprovedBy(assetTransaction.getCreatedBy());
		assetTransaction.setApprovedDate(new Date());
		assetTransaction.setAssetTransactionCode(getNextTransactionCode(AssetTransaction.TRANSACTIONTYPE_STOCKADJUSTMENT));
		
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		
		em.persist(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		if(assetTransactionItems!=null)
		{
			String subType = assetTransaction.getAssetTransactionSubType();
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
				
				if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_EQUIPMENT))
					assetTransactionItem.setAssetTransactionQuantity(1);
				
				if(assetTransactionItem.getAssetTransactionQuantity()==null) continue;
				
				if(assetTransactionItem.getAssetModel()==null) continue;
				
				AssetModel assetModel = assetTransactionItem.getAssetModel();
				assetModel = em.find(AssetModel.class, assetModel.getAssetModelId());
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(i+1);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				
				if(StringUtils.equalsIgnoreCase(subType, AssetTransaction.TRANSACTIONSUBTYPE_IN))
				{
					if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_EQUIPMENT))
						assetTransactionItem.setAssetTag(getNextAssetTag(AssetModel.ASSETTYPE_EQUIPMENT, assetModel.getAssetModelCode()));
					else 
						assetTransactionItem.setAssetTag(getNextAssetTag(AssetModel.ASSETTYPE_COMPONENT, assetModel.getAssetModelCode()));
				}
				
				
				if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_EQUIPMENT))
				{
					if(StringUtils.equalsIgnoreCase(subType, AssetTransaction.TRANSACTIONSUBTYPE_IN))
					{
						AssetEquipment assetEquipment = new AssetEquipment();
						
						AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetModel,assetTransactionItem.getSerialNo());
						assetEquipment.setAssetEquipmentPK(assetEquipmentPK);
						assetEquipment.setLocation(assetTransactionItem.getLocation());
						assetEquipment.setAssetTag(assetTransactionItem.getAssetTag());
						assetEquipment.setUnitPrice(0f);
						assetEquipment.setDateCreated(new Date());
						assetEquipment.setCreatedBy(assetTransaction.getCreatedBy());
						assetEquipment.setDateModified(new Date());
						assetEquipment.setModifiedBy(assetTransaction.getCreatedBy());
						assetEquipment.setAssetEquipmentStatus(AssetModel.ASSETSTATUS_ACTIVE);
						assetEquipment.setCompanyCode(assetTransactionItem.getCompanyCode());
						em.persist(assetEquipment);
					}
					else if(StringUtils.equalsIgnoreCase(subType, AssetTransaction.TRANSACTIONSUBTYPE_OUT))
					{
						AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetModel,assetTransactionItem.getSerialNo());
						AssetEquipment assetEquipment = em.find(AssetEquipment.class, assetEquipmentPK);
						if(assetEquipment!=null) {
							assetEquipment.setAssetEquipmentStatus(AssetModel.ASSETSTATUS_INACTIVE);
							assetEquipment.setCompanyCode(assetTransactionItem.getCompanyCode());
							em.merge(assetEquipment);
						}
					}
				}
				else if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_COMPONENT))
				{
					AssetComponentPK assetComponentPK = new AssetComponentPK(assetModel, assetTransactionItem.getLocation(),assetTransaction.getCompanyCode());
					
					AssetComponent assetComponent = em.find(AssetComponent.class, assetComponentPK);
					if(assetComponent!=null)
					{
						if(StringUtils.equalsIgnoreCase(subType, AssetTransaction.TRANSACTIONSUBTYPE_IN))
						{
							createAssetConsumption(assetComponent,assetTransactionItem,assetTransaction);
							assetComponent.setQuantity(assetComponent.getQuantity()+assetTransactionItem.getAssetTransactionQuantity());
						}
						else if(StringUtils.equalsIgnoreCase(subType, AssetTransaction.TRANSACTIONSUBTYPE_OUT))
						{
							//this must be used
							Float assetPrice = getNextAssetPrice(assetTransaction,assetComponent, assetTransactionItem.getAssetTransactionQuantity(), new ArrayList<AssetIssueOrderDetail>());
							assetTransactionItem.setAssetPrice(assetPrice);
							
							assetComponent.setQuantity(assetComponent.getQuantity()-assetTransactionItem.getAssetTransactionQuantity());
						}
						assetComponent.setDateModified(new Date());
						assetComponent.setModifiedBy(assetTransaction.getCreatedBy());
						em.merge(assetComponent);
					}
					else
					{
						assetComponent = new AssetComponent();
						assetComponent.setQuantity(assetTransactionItem.getAssetTransactionQuantity());
						assetComponent.setAssetComponentPK(assetComponentPK );
						assetComponent.setDateCreated(new Date());
						assetComponent.setCreatedBy(assetTransaction.getCreatedBy());
						assetComponent.setDateModified(new Date());
						assetComponent.setModifiedBy(assetTransaction.getCreatedBy());
						
						em.persist(assetComponent);
					}
				}
				
				em.persist(assetTransactionItem);
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}

	public void createReceiveNewDeliveryOrder(AssetTransaction assetTransaction,Date startDate,Date endDate) {
		
		String assetType = assetTransaction.getAssetType();
		
		AssetTransaction newAssetTransaction = new AssetTransaction();
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_DELIVERYORDER);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		
		assetTransaction.setAssetTransactionCode(getNextTransactionGenCode(AssetTransaction.TRANSACTIONTYPE_DELIVERYORDER));
		
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		
		em.persist(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		if(assetTransactionItems!=null)
		{
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
				if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_EQUIPMENT))
					assetTransactionItem.setAssetTransactionQuantity(1);
				
				if(assetTransactionItem.getAssetTransactionQuantity()==null) continue;
				
				AssetModel assetModel = assetTransactionItem.getAssetModel();
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(i+1);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				em.persist(assetTransactionItem);
				
				if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_EQUIPMENT))
				{
					AssetEquipment assetEquipment = new AssetEquipment();
					assetEquipment.setCompanyCode(assetTransactionItem.getCompanyCode());
					AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetModel,assetTransactionItem.getSerialNo());
					assetEquipment.setAssetEquipmentPK(assetEquipmentPK);
//					assetEquipment.setSerialNo(assetTransactionItem.getSerialNo());
					assetEquipment.setLocation(assetTransactionItem.getLocation());
					assetEquipment.setAssetTag(assetTransactionItem.getAssetTag());
					assetEquipment.setUnitPrice(assetTransactionItem.getAssetPrice());
					assetEquipment.setDateCreated(new Date());
					assetEquipment.setCreatedBy(assetTransaction.getCreatedBy());
					assetEquipment.setDateModified(new Date());
					assetEquipment.setModifiedBy(assetTransaction.getCreatedBy());
					assetEquipment.setAssetEquipmentStatus(AssetModel.ASSETSTATUS_ACTIVE);
					assetEquipment.setEffectiveStartDate(startDate);
					assetEquipment.setEffectiveEndDate(endDate);
					assetEquipment.setCompanyCode(assetTransactionItem.getCompanyCode());
					em.merge(assetEquipment);
				}
				else if(StringUtils.equalsIgnoreCase(assetType, AssetModel.ASSETTYPE_COMPONENT))
				{
					AssetComponentPK assetComponentPK = new AssetComponentPK(assetModel, assetTransaction.getToLocation(),assetTransactionItem.getCompanyCode());
					
					AssetComponent assetComponent = em.find(AssetComponent.class, assetComponentPK);
					if(assetComponent!=null)
					{
						assetComponent.setQuantity(assetComponent.getQuantity()+assetTransactionItem.getAssetTransactionQuantity());					
						assetComponent.setDateModified(new Date());
						assetComponent.setModifiedBy(assetTransaction.getCreatedBy());
						em.merge(assetComponent);
					}
					else
					{
						assetComponent = new AssetComponent();
						assetComponent.setQuantity(assetTransactionItem.getAssetTransactionQuantity());
						assetComponent.setAssetComponentPK(assetComponentPK );
						assetComponent.setDateCreated(new Date());
						assetComponent.setCreatedBy(assetTransaction.getCreatedBy());
						assetComponent.setDateModified(new Date());
						assetComponent.setModifiedBy(assetTransaction.getCreatedBy());
						em.persist(assetComponent);
					}
					
					createAssetConsumption(assetComponent, assetTransactionItem, newAssetTransaction);
					
				}
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}

	private void createAssetConsumption(AssetComponent assetComponent,AssetTransactionItem assetTransactionItem,AssetTransaction assetTransaction)
	{
		AssetConsumption assetConsumption = new AssetConsumption();
		assetConsumption.setAssetComponent(assetComponent);
		assetConsumption.setQuantityReceived(assetTransactionItem.getAssetTransactionQuantity());
		assetConsumption.setQuantityUsed(0);
		assetConsumption.setAssetConsumptionStatus(true);
		assetConsumption.setTransactionType(assetTransaction.getAssetTransactionType());
		if(assetTransactionItem.getAssetPrice()==null)
			assetConsumption.setUnitPrice(0f);
		else	
			assetConsumption.setUnitPrice(assetTransactionItem.getAssetPrice());
		
		Vendor vendor = assetTransaction.getVendor();
		if(vendor!=null)
			assetConsumption.setVendorId(vendor.getVendorId());
		
		assetConsumption.setRefNo(assetTransaction.getAssetTransactionCode());
		assetConsumption.setDateCreated(new Date());
		assetConsumption.setCreatedBy(assetTransaction.getCreatedBy());
		assetConsumption.setDateModified(new Date());
		assetConsumption.setModifiedBy(assetTransaction.getCreatedBy());
		em.persist(assetConsumption);
	}
	
	private void createAssetConsumptionNonVendor(AssetComponent assetComponent,AssetTransaction assetTransaction,int qtyConsumption, List<AssetIssueOrderDetail> orders)
	{
		AssetConsumption assetConsumption = new AssetConsumption();
		assetConsumption.setAssetComponent(assetComponent);
		assetConsumption.setQuantityReceived(qtyConsumption);
		assetConsumption.setQuantityUsed(qtyConsumption);
		assetConsumption.setAssetConsumptionStatus(false);
		assetConsumption.setTransactionType(assetTransaction.getAssetTransactionType());
		assetConsumption.setUnitPrice(0f);
		assetConsumption.setRefNo(assetTransaction.getAssetTransactionCode());
		assetConsumption.setDateCreated(new Date());
		assetConsumption.setCreatedBy(assetTransaction.getCreatedBy());
		assetConsumption.setDateModified(new Date());
		assetConsumption.setModifiedBy(assetTransaction.getCreatedBy());
		em.persist(assetConsumption);
		
		AssetConsumptionDetail assetConsumptionDetail = new AssetConsumptionDetail();
		assetConsumptionDetail.setAssetConsumption(assetConsumption);
		assetConsumptionDetail.setQuantityBefore(qtyConsumption);
		assetConsumptionDetail.setQuantityUsed(qtyConsumption);
		assetConsumptionDetail.setDateModified(new Date());
		assetConsumptionDetail.setDateCreated(new Date());
		assetConsumptionDetail.setRefNo(assetTransaction.getAssetTransactionCode());
		assetConsumptionDetail.setTransactionType(assetTransaction.getAssetTransactionType());
		
		em.persist(assetConsumptionDetail);
		
		// add new logis here
		AssetIssueOrderDetail orderDetail = new AssetIssueOrderDetail();
		orderDetail.setDateCreated(new Date());
		orderDetail.setCreatedByName(assetTransaction.getCreatedBy());
		orderDetail.setDateModified(new Date());
		orderDetail.setModifiedByName(assetTransaction.getCreatedBy());
		orderDetail.setQuantity(qtyConsumption);
		orderDetail.setUnitPrice(assetConsumption.getUnitPrice());
		orders.add(orderDetail);
	}

	public SearchResult searchIssueOrder(SearchCriteria searchCriteria) {
		
		if(searchCriteria.getCurPage()==null)
			searchCriteria.setCurPage(1);
		
		AssetTransactionPaginationHelper helper = new AssetTransactionPaginationHelper();
		return helper.getSearchResultFromQueryHelper(em, searchCriteria);
	}
	
	public SearchResult searchStockAdjustment(SearchCriteria searchCriteria) {

		if(searchCriteria.getCurPage()==null)
			searchCriteria.setCurPage(1);
		
		StockAdjusmentPaginationHelper helper = new StockAdjusmentPaginationHelper();
		return helper.getSearchResultFromQueryHelper(em, searchCriteria);
	}
	
	public static class AssetTransactionPaginationHelper extends PaginationHelper<AssetTransaction> {

		@Override
		public String[] getValidColumnName() {
			return new String[]{"assetTransactionCode","assetTransactionType","assetTransactionStatus","dateModified"};
		}
		
		@Override
		public String[] getValidSortName() {
			return new String[]{"assetTransactionCode","assetTransactionType","assetTransactionStatus","modifiedBy","dateModified"};
		}

		@Override
		public String getDefaultSortName() {
			return "dateModified";
		}
		
		@Override
		public QueryHelper getQueryHelper() {
			QueryHelper queryHelper = new QueryHelper();
			queryHelper.select("select assetTransaction from AssetTransaction assetTransaction where assetTransactionType in ('IO','ET','FT','SOI','INH')");
			return queryHelper;
		}
	}
	
	public static class StockAdjusmentPaginationHelper extends PaginationHelper<AssetTransaction> {

		@Override
		public String[] getValidColumnName() {
			return new String[]{"assetTransactionCode","assetTransactionType","assetTransactionStatus","modifiedBy","dateModified"};
		}
		
		@Override
		public String[] getValidSortName() {
			return new String[]{"assetTransactionCode","assetTransactionType","assetTransactionStatus","modifiedBy","dateModified"};
		}

		@Override
		public String getDefaultSortName() {
			return "assetTransactionCode";
		}
		
		@Override
		public QueryHelper getQueryHelper() {
			QueryHelper queryHelper = new QueryHelper();
			queryHelper.select("select assetTransaction from AssetTransaction assetTransaction where assetTransactionType ='SAJ'");
			return queryHelper;
		}
	}

	public void rejectStockTransferEquipments(Integer assetTransactionId) {
		
		
	}
	
	public void createSalesOfItems(
			AssetTransaction assetTransaction) {
		AssetTransaction newAssetTransaction = new AssetTransaction();
		
		
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_SALESOFITEMS);		
		
		
		assetTransaction.setAssetType(AssetModel.ASSETTYPE_EQUIPMENT);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		
		assetTransaction.setDateCreated(new Date());
		assetTransaction.setDateModified(new Date());
		assetTransaction.setModifiedBy(assetTransaction.getCreatedBy());
		assetTransaction.setApprovedDate(new Date());
		assetTransaction.setApprovedBy(assetTransaction.getCreatedBy());
		
		assetTransaction.setAssetTransactionCode(getNextTransactionCode(AssetTransaction.TRANSACTIONTYPE_SALESOFITEMS));
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		em.persist(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		int idx=1;
		if(assetTransactionItems!=null)
		{
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
				AssetModel assetModel = assetTransactionItem.getAssetModel();
				if(assetTransactionItem.isDeleted()) continue;
				if(assetTransactionItem.getSerialNo()==null) continue;
				
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(idx);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				em.persist(assetTransactionItem);
				idx++;
				
				AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetModel,assetTransactionItem.getSerialNo());
				AssetEquipment assetEquipment = em.find(AssetEquipment.class, assetEquipmentPK);
				if(assetEquipment!=null) {
					
					assetEquipment.setCompanyCode(assetTransaction.getToCompanyCode());
					em.merge(assetEquipment);
				}
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}
	
	public void createRepairPurchaseOrder(AssetTransaction assetTransaction) {
		
		AssetTransaction newAssetTransaction = new AssetTransaction();
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_PURCHASEORDERREPAIR);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		assetTransaction.setAssetType(AssetModel.ASSETTYPE_EQUIPMENT);
		//assetTransaction.setDateCreated(new Date());
		assetTransaction.setAssetTransactionCode(getNextTransactionGenCode(AssetTransaction.TRANSACTIONTYPE_PURCHASEORDERREPAIR));
		
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		
		
		Location vendorLocation = assetTransaction.getToLocation();
		
		em.persist(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		if(assetTransactionItems!=null)
		{
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
				assetTransactionItem.setAssetTransactionQuantity(1);
				if(assetTransactionItem.getAssetTransactionQuantity()==null) continue;
				
				AssetModel assetModel = assetTransactionItem.getAssetModel();
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(i+1);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				em.persist(assetTransactionItem);
				
				AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetModel,assetTransactionItem.getSerialNo());
				AssetEquipment assetEquipment = em.find(AssetEquipment.class, assetEquipmentPK);
				if(assetEquipment!=null)
				{
					
					assetEquipment.setLocation(vendorLocation);
					assetEquipment.setAssetEquipmentStatus(AssetModel.ASSETSTATUS_REPAIR);
					em.merge(assetEquipment);
				}
				
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}
	
	
public void updateRepairPurchaseOrder(AssetTransaction assetTransaction) {
	
		Query query = em.createQuery("select assetTransaction from AssetTransaction assetTransaction where assetTransaction.remarks=:poCode and assetTransaction.assetTransactionType='POR'");
		query.setParameter("poCode", assetTransaction.getRemarks());
		List<AssetTransaction> atToDelete=  query.getResultList();
		if(atToDelete!=null){
		AssetTransaction at = em.find(AssetTransaction.class, atToDelete.get(0).getAssetTransactionId());
		List<AssetTransactionItem> atItems = at.getAssetTransactionItems();
		if(atItems!=null)
		{
			Iterator<AssetTransactionItem> i = atItems.iterator();
			while(i.hasNext())
			{
				AssetTransactionItem atItem = i.next();				
					atItem = em.getReference(AssetTransactionItem.class, atItem.getAssetTransactionItemPK());
					em.remove(atItem);					
				}
		}
		em.remove(at);	
		}
			
		AssetTransaction newAssetTransaction = new AssetTransaction();
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_PURCHASEORDERREPAIR);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		assetTransaction.setAssetType(AssetModel.ASSETTYPE_EQUIPMENT);
		//assetTransaction.setDateCreated(new Date());
		assetTransaction.setAssetTransactionCode(getNextTransactionGenCode(AssetTransaction.TRANSACTIONTYPE_PURCHASEORDERREPAIR));
		
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		
		
		Location vendorLocation = assetTransaction.getToLocation();
		
		em.persist(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		if(assetTransactionItems!=null)
		{
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
				assetTransactionItem.setAssetTransactionQuantity(1);
				if(assetTransactionItem.getAssetTransactionQuantity()==null) continue;
				
				AssetModel assetModel = assetTransactionItem.getAssetModel();
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(i+1);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				em.persist(assetTransactionItem);
				
				AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetModel,assetTransactionItem.getSerialNo());
				AssetEquipment assetEquipment = em.find(AssetEquipment.class, assetEquipmentPK);
				if(assetEquipment!=null)
				{
					
					assetEquipment.setLocation(vendorLocation);
					assetEquipment.setAssetEquipmentStatus(AssetModel.ASSETSTATUS_REPAIR);
					em.merge(assetEquipment);
				}
				
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}
	
	public void createReceiveRepairDeliveryOrder(AssetTransaction assetTransaction) {

		AssetTransaction newAssetTransaction = new AssetTransaction();
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_DELIVERYORDERREPAIR);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		assetTransaction.setAssetTransactionCode(getNextTransactionGenCode(AssetTransaction.TRANSACTIONTYPE_DELIVERYORDERREPAIR));
		assetTransaction.setAssetType(AssetModel.ASSETTYPE_EQUIPMENT);
		
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		
		em.persist(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		Location toLocation = assetTransaction.getToLocation();
		
		if(assetTransactionItems!=null)
		{
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
			
				assetTransactionItem.setAssetTransactionQuantity(1);
				
				if(assetTransactionItem.getAssetTransactionQuantity()==null) continue;
				
				AssetModel assetModel = assetTransactionItem.getAssetModel();
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(i+1);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				em.persist(assetTransactionItem);
				
				AssetEquipmentPK assetEquipmentPK = new AssetEquipmentPK(assetModel,assetTransactionItem.getSerialNo());
				AssetEquipment assetEquipment = em.find(AssetEquipment.class, assetEquipmentPK);
				if(assetEquipment!=null)
				{
					assetEquipment.setLocation(toLocation);
					if(assetTransactionItem.getRemarks().equalsIgnoreCase(AssetModel.ASSETSTATUS_ACTIVE))
					assetEquipment.setAssetEquipmentStatus(AssetModel.ASSETSTATUS_ACTIVE);
					else
						assetEquipment.setAssetEquipmentStatus(AssetModel.ASSETSTATUS_FAULT);
					em.merge(assetEquipment);
				}
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}

	public void createWorkOrderPartChanges(AssetTransaction assetTransaction) {
		
		AssetTransaction newAssetTransaction = new AssetTransaction();
		assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_WORKORDER);
		assetTransaction.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
		assetTransaction.setAssetTransactionCode(getNextTransactionGenCode(AssetTransaction.TRANSACTIONTYPE_WORKORDER));
		assetTransaction.setAssetType(AssetModel.ASSETTYPE_EQUIPMENT);
		
		BeanUtils.copyProperties(assetTransaction,newAssetTransaction);
		
		em.persist(newAssetTransaction);
		
		List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
		
		if(assetTransactionItems!=null)
		{
			for(int i=0;i<assetTransactionItems.size();i++)
			{
				AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
			
				assetTransactionItem.setAssetTransactionQuantity(1);
				
				if(assetTransactionItem.getAssetTransactionQuantity()==null) continue;
				
				AssetTransactionItemPK assetTransactionItemPK = new AssetTransactionItemPK();
				assetTransactionItemPK.setAssetTransaction(newAssetTransaction);
				assetTransactionItemPK.setItemNo(i+1);
				assetTransactionItem.setAssetTransactionItemPK(assetTransactionItemPK);
				assetTransactionItem.setAssetTransactionStatus(AssetTransaction.TRANSACTIONSTATUS_APPROVED);
				em.persist(assetTransactionItem);
			}
		}
		
		assetTransaction.setAssetTransactionId(newAssetTransaction.getAssetTransactionId());
	}
	
	public List<String> isAvaliable(AssetTransaction assetTransaction)
	{
		List<String> message = new ArrayList<String>();
		SearchCriteria searchCriteria = new SearchCriteria();
		Query query =  em.createQuery("select assetTransaction from AssetTransaction assetTransaction, AssetTransactionItem item where " +
				" assetTransaction.assetTransactionId=item.assetTransactionItemPK.assetTransaction.assetTransactionId and " +
				//" assetTransaction.assetTransactionType=:assetTransactionType and " +
				" assetTransaction.fromLocation=:fromLocation and " +
				" assetTransaction.companyCode=:companyCode and " +
				" item.assetTransactionStatus in (:assetTransactionStatus) and " +
				" item.serialNo=:serialNo");
		
		List<AssetTransactionItem> items = assetTransaction.getAssetTransactionItems();
		if(CollectionUtils.isNotEmpty(items)){
			for (AssetTransactionItem assetTransactionItem : items) {
				if(!assetTransactionItem.isDeleted()){
					//query.setParameter("assetTransactionType", assetTransaction.getAssetTransactionType());
					query.setParameter("fromLocation", assetTransaction.getFromLocation());
					query.setParameter("companyCode", assetTransaction.getCompanyCode());
					query.setParameter("serialNo", assetTransactionItem.getSerialNo());
					List<String> status = Arrays.asList(new String[]{AssetTransaction.TRANSACTIONSTATUS_PENDING});
					query.setParameter("assetTransactionStatus", status);
					List<AssetTransaction> assetTransactionList = query.getResultList();
					if(assetTransactionList!=null){
						int result = assetTransactionList.size();
					//Long result = (Long)query.getSingleResult();
					if(result > 0){
						if(assetTransaction.getAssetTransactionId()==null) {
							message.add(assetTransactionItem.getSerialNo());						
						}
						else
						{
								for(AssetTransaction at : assetTransactionList){
									if(at.getAssetTransactionId().intValue() != assetTransaction.getAssetTransactionId().intValue()){
										message.add(assetTransactionItem.getSerialNo());
										break;
									}
									    
								}
						}
					}
					}
					searchCriteria.addSearchCriteria("serialNo", assetTransactionItem.getSerialNo());
					searchCriteria.addSearchCriteria("assetModelId", assetTransactionItem.getAssetModel().getAssetModelId());
					AssetEquipment assetEquipment = assetModelService.findAssetEquipment(searchCriteria);
					if(assetEquipment!=null)
					{
						if(assetEquipment.getLocation()!=null && assetTransaction.getFromLocation()!=null) {
						if(assetEquipment.getLocation().getLocationId().intValue()!= assetTransaction.getFromLocation().getLocationId().intValue())
							message.add(assetTransactionItem.getSerialNo());
						}
						
						if(StringUtils.isNotEmpty(assetEquipment.getCompanyCode()) && StringUtils.isNotEmpty(assetTransaction.getCompanyCode())){
						if(!(assetEquipment.getCompanyCode().equalsIgnoreCase(assetTransaction.getCompanyCode())))
								message.add(assetTransactionItem.getSerialNo());
						}
					}
					Query inner =  em.createQuery("from AssetModel where assetModelId=:assetModelId");
					inner.setParameter("assetModelId", assetTransactionItem.getAssetModel().getAssetModelId());
					AssetModel assetModel = (AssetModel)inner.getSingleResult();
					assetTransactionItem.getAssetModel().setAssetModelName(assetModel.getAssetModelName());
				}
			}
//			if(CollectionUtils.isNotEmpty(message)){
//				assetTransaction.getAssetTransactionItems().clear();
//			}
		}
		
				
		return message;
	}
}
